package com.shoutao.website.utils.localcache;

import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;


/**
* @Description:
* @Param:
* @return:
* @Author: cqin
* @Date: 2018/12/18
*/
public class CacheFactory {

    private static Logger logger = LoggerFactory.getLogger(CacheFactory.class);
    private static Map<String, LoadingCache> cacheMap = new ConcurrentHashMap<>();
    /**
     * 默认缓存时间
     */
    private static final int DEFAULT_TIMEOUT_MINUTE = 5;

    private CacheFactory() {

    }


    /**
     * 根据key获取缓存
     * @param key
     * @param cacheLoader
     * @return
     */
    public static Object getCacheByKey(String key, final ILocalCacheLoader cacheLoader) {
        LoadingCache cache = getLoadingCache(key, cacheLoader);
        try {
            Optional result = (Optional) cache.get(key);
            if (result.isPresent()) {
                return result.get();
            } else {
                return null;
            }
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * 获取LoadingCache的实例
     * @param key
     * @param cacheLoader
     * @return
     */
    private static LoadingCache getLoadingCache(String key, final ILocalCacheLoader cacheLoader) {
        if (cacheMap.containsKey(key)) {
            return cacheMap.get(key);
        } else {
            int timeOutMinutes = cacheLoader.timeOutMinute(key);
            if (timeOutMinutes <= 0) {
                timeOutMinutes = DEFAULT_TIMEOUT_MINUTE;
            }
            LoadingCache<String, Optional> cache = CacheBuilder.newBuilder()
                    .refreshAfterWrite(timeOutMinutes, TimeUnit.MINUTES)
                    .build(new CacheLoader<String, Optional>() {
                        @Override
                        public Optional load(String key) throws CacheLoadFailException {
                            return cacheLoader.loader(key);
                        }
                    });

            cacheMap.put(key, cache);
            return cache;
        }
    }
}
